package com.cellulam.framework.scaffold.generate.db;

import com.google.common.collect.Lists;
import com.cellulam.framework.scaffold.generate.utils.CamelCaseUtils;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

@Getter
@Setter
public class TableMetaInfo {

    private boolean enableLocalDateTime = false;
    private String sqlTableName;
    private String tableName;
    private Set<Class<?>> importedClazzs = new HashSet<>();
    private Set<String> importedStr = new HashSet<>();
    private ColumnField pk;
    private List<ColumnField> columns;
    private List<ColumnField> columnsNoPk = new ArrayList<>();
    private String removePrefix;
    private boolean enablePrimitiveType = false;
    private List<ColumnField> uniqKeyFields = Lists.newArrayList();

    public boolean hasUniqKey() {
        return !CollectionUtils.isEmpty(uniqKeyFields);
    }

    public String getUniqKeyParamsDao() {
        if (CollectionUtils.isEmpty(uniqKeyFields)) {
            return null;
        }
        StringBuilder params = new StringBuilder();
        uniqKeyFields.forEach(x -> {
            params.append("@Param(\"" + x.getFieldName() + "\")");
            params.append(x.getFieldTypePrimitiveStr());
            params.append(" ");
            params.append(x.getFieldName());
            params.append(", ");
        });
        return params.substring(0, params.lastIndexOf(","));
    }

    public String getUniqKeyParams() {
        if (CollectionUtils.isEmpty(uniqKeyFields)) {
            return null;
        }
        StringBuilder params = new StringBuilder();
        uniqKeyFields.forEach(x -> {
            params.append(x.getFieldTypePrimitiveStr());
            params.append(" ");
            params.append(x.getFieldName());
            params.append(", ");
        });
        return params.substring(0, params.lastIndexOf(","));
    }


    public String getUniqKeyParamsNoType() {
        if (CollectionUtils.isEmpty(uniqKeyFields)) {
            return null;
        }
        StringBuilder params = new StringBuilder();
        uniqKeyFields.forEach(x -> {
            params.append(x.getFieldName());
            params.append(", ");
        });
        return params.substring(0, params.lastIndexOf(","));
    }

    public String getBeanName() {
        if (StringUtils.isNotEmpty(removePrefix) && tableName.startsWith(removePrefix.trim())) {
            return CamelCaseUtils.toCapitalizeCamelCase(tableName.substring(removePrefix.trim().length()));
        } else {
            return CamelCaseUtils.toCapitalizeCamelCase(tableName);
        }
    }

    public void addImported(Class<?> clazz) {
        importedClazzs.add(clazz);
        importedStr.add(clazz.getName());
    }

    public void addImportedStr(String clazzName) {
        importedStr.add(clazzName);
    }

    public String getUnderscoreName() {
        return CamelCaseUtils.toHumpWord(tableName);
    }

    public String getStripingName() {
        return getUnderscoreName().replace("_", "-");
    }

    public List<ColumnField> getColumnsNoPk() {
        if (pk == null) {
            return columns;
        }
        if (!columnsNoPk.isEmpty()) {
            return columnsNoPk;
        }
        columnsNoPk.addAll(columns);
        for (Iterator<ColumnField> iter = columnsNoPk.iterator(); iter.hasNext(); ) {
            if (iter.next().getColumnName().equals(pk.getColumnName())) {
                iter.remove();
                break;
            }
        }
        return columnsNoPk;
    }

    public String getSqlTableName() {
        return StringUtils.isBlank(sqlTableName) ? tableName : sqlTableName;
    }

    public void setSqlTableName(String sqlTableName) {
        this.sqlTableName = sqlTableName;
    }

    public boolean containsJson() {
        for (ColumnField cf : getColumns()) {
            if (cf.isJson()) {
                return true;
            }
        }
        return false;
    }

    public boolean generateDel() {
        for (ColumnField field : getColumns()) {
            if (field.getColumnName().equalsIgnoreCase("is_del")) {
                return true;
            }
        }
        return false;
    }

    public boolean hasCreateUser() {
        for (ColumnField field : getColumns()) {
            if (field.getColumnType().equalsIgnoreCase("integer") && field.getColumnName().equalsIgnoreCase("create_user")) {
                return true;
            }
        }
        return false;
    }

    public boolean hasUpdateUser() {
        for (ColumnField field : getColumns()) {
            if (field.getColumnType().equalsIgnoreCase("integer") && field.getColumnName().equalsIgnoreCase("update_user")) {
                return true;
            }
        }
        return false;
    }

    public List<String> getJsonTypes() {
        List<String> types = Lists.newArrayList();
        for (ColumnField cf : getColumns()) {
            if (cf.isJson()) {
                types.add(cf.getFieldTypeStr());
            }
        }
        return types;
    }

    public List<String> getEnumComments() {
        List<String> enumComments = Lists.newArrayList();
        for (ColumnField columnField : getColumns()) {
            if (columnField.isEnum()) {
                enumComments.add(columnField.getComment());
            }
        }
        return enumComments;
    }
}
